/*
 * regerror - 错误代码扩展
 *
 * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
 *
 * Development of this software was funded, in part, by Cray Research Inc.,
 * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
 * Corporation, none of whom are responsible for the results.  The author
 * thanks all of them.
 *
 * Redistribution and use in source and binary forms -- with or without
 * modification -- are permitted for any purpose, provided that
 * redistributions in source form retain this entire copyright notice and
 * indicate the origin and nature of any modifications.
 *
 * I'd appreciate being given credit for this package in the documentation
 * of software which uses it, but that is not a requirement.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * src/backend/regex/regerror.c
 *
 */

#include "regex/regguts.h"

/*未知错误说明*/
static const char unk[] = "*** unknown regex error code 0x%x ***";

/*结构体用于映射代码、代码名称和说明*/
static const struct rerr
{
	int			code;
	const char *name;
	const char *explain;
}			rerrs[] =

{
	/*实际表格是从 regex.h 构建的*/
#include "regex/regerrs.h"		/* pgrminclude 忽略 */
	{
		-1, "", "oops"
	},							/*代码中特殊处理的说明*/
};

/*
 * pg_regerror - 错误编号的接口
*/
/* ARGSUSED */
size_t							/*实际所需空间（包括 NUL）*/
pg_regerror(int fc_errcode,		/*错误代码，或 REG_ATOI 或 REG_ITOA*/
			const regex_t *fc_preg,	/*相关的 regex_t（目前未使用）*/
			char *fc_errbuf,		/*结果缓冲区（除非 errbuf_size==0）*/
			size_t fc_errbuf_size) /*errbuf 中可用空间，可以是 0*/
{
	const struct rerr *fc_r;
	const char *fc_msg;
	char		fc_convbuf[sizeof(unk) + 50];	/*50 = 对于 int 来说足够多*/
	size_t		fc_len;
	int			fc_icode;

	switch (fc_errcode)
	{
		case REG_ATOI:			/*将名称转换为数字*/
			for (fc_r = rerrs; fc_r->code >= 0; fc_r++)
				if (strcmp(fc_r->name, fc_errbuf) == 0)
					break;
			sprintf(fc_convbuf, "%d", fc_r->code);	/*未知时为 -1*/
			fc_msg = fc_convbuf;
			break;
		case REG_ITOA:			/*将数字转换为名称*/
			fc_icode = atoi(fc_errbuf);	/*如果失败这不是我们的问题*/
			for (fc_r = rerrs; fc_r->code >= 0; fc_r++)
				if (fc_r->code == fc_icode)
					break;
			if (fc_r->code >= 0)
				fc_msg = fc_r->name;
			else
			{					/*未知；告诉他号码*/
				sprintf(fc_convbuf, "REG_%u", (unsigned) fc_icode);
				fc_msg = fc_convbuf;
			}
			break;
		default:				/*一个真实的，正常的错误代码*/
			for (fc_r = rerrs; fc_r->code >= 0; fc_r++)
				if (fc_r->code == fc_errcode)
					break;
			if (fc_r->code >= 0)
				fc_msg = fc_r->explain;
			else
			{					/*未知；说出来*/
				sprintf(fc_convbuf, unk, fc_errcode);
				fc_msg = fc_convbuf;
			}
			break;
	}

	fc_len = strlen(fc_msg) + 1;		/*所需空间，包括 NUL*/
	if (fc_errbuf_size > 0)
	{
		if (fc_errbuf_size > fc_len)
			strcpy(fc_errbuf, fc_msg);
		else
		{						/*截断以适应*/
			memcpy(fc_errbuf, fc_msg, fc_errbuf_size - 1);
			fc_errbuf[fc_errbuf_size - 1] = '\0';
		}
	}

	return fc_len;
}
